﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using TjZheng.CMS.Process.Business;
using TjZheng.Framework;
using TjZheng.Logging;
using TjZheng.Mvc;
using TjZheng.Power.Business;
using TjZheng.Power.DataEntity;

using TjZheng.CMS.Process.DataEntity;
using TjZheng.Power.RedisEntity;
using TjZheng.Redis;
using TjZheng.Cache;

namespace TjZheng.CMS.Process
{
    /// <summary>
    /// 权限过滤器
    /// </summary>
    //[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class AuthorizeFilter : TjZhengFilter
    {
        /// <summary>
        /// 是否检查用户权限
        /// </summary>
        protected bool IsCheckUserPower
        {
            get
            {
                return ConfigHelper.GetBoolValue("IsCheckUserPower", true);
            }
        }
        /// <summary>
        /// 是否从Redis检查用户权限
        /// </summary>
        protected bool IsCheckUserPowerRedis
        {
            get
            {
                return ConfigHelper.GetBoolValue("IsCheckUserPowerRedis", true);
            }
        }
        /// <summary>
        /// 权限校验
        /// </summary>
        protected PowerType PowerType { get; set; }
        public AuthorizeFilter()
            : this(PowerType.CheckAll)
        {
        }
        public AuthorizeFilter(PowerType PowerType)
        {
            this.PowerType = PowerType;
            //if (this.PowerType == PowerType.CheckAll)
            //{
            //    //全部校验优先级低于其他校验
            //    this.Order = 0;
            //}
        }
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }
            if (filterContext.IsChildAction)
            {
                return;
            }
            //var objPowerType = filterContext.HttpContext.GetItems("PowerType");
            //if (objPowerType != null && (PowerType)objPowerType != PowerType.CheckAll)
            //{
            //    return;
            //}
            switch (this.PowerType)
            {
                case PowerType.None:
                    CheckNone(filterContext);
                    break;
                case PowerType.CheckLogin:
                    CheckLogin(filterContext);
                    break;
                default:
                    CheckAll(filterContext);
                    break;
            }

        }
        /// <summary>
        /// 无需任何权限校验
        /// </summary>
        /// <param name="filterContext"></param>
        protected virtual void CheckNone(ActionExecutingContext filterContext)
        {
            filterContext.HttpContext.SetItems("PowerType", this.PowerType);
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                return;
            }
            string controllerName = filterContext.RouteData.GetRequiredString("controller");
            string actionName = filterContext.RouteData.GetRequiredString("action");
            string areaName = filterContext.RouteData.DataTokens["area"] != null ? filterContext.RouteData.DataTokens["area"].ToString() : "";
            BizPowerInfo objBizPowerInfo = new BizPowerInfo();
            var objPowerInfo = objBizPowerInfo.GetRecord(string.Format("ControllerName='{0}' AND ActionName='{1}' AND AreaName='{2}'", controllerName, actionName, areaName));
            if (objPowerInfo != null && objPowerInfo.HasChild == 1)
            {
                var objButtonList = objBizPowerInfo.GetList(string.Format("ParentId={0} AND PowerType=2 AND IsDisplay=1", objPowerInfo.Id));
                if (objButtonList.IsNoNull())
                {
                    var objButtonTool = new ButtonTool();
                    objButtonList = objButtonList.OrderBy(c => c.SortIndex).ToList();
                    objButtonTool.AddItems(objButtonList.ConvertToButtonItemList().ToList());
                    filterContext.HttpContext.SetItems("ButtonTool", objButtonTool);
                }
            }
        }
        /// <summary>
        /// 仅登录校验
        /// </summary>
        /// <param name="filterContext"></param>
        protected virtual void CheckLogin(ActionExecutingContext filterContext)
        {
            if (!IsLogin(filterContext))
            {
                return;
            }
            CheckNone(filterContext);
        }
        /// <summary>
        /// 全部校验
        /// </summary>
        /// <param name="filterContext"></param>
        protected virtual void CheckAll(ActionExecutingContext filterContext)
        {
            if (IsLogin(filterContext))
            {
                if (IsCheckUserPower)
                {
                    ChekeUserPower(filterContext);
                }
                else
                {
                    ChekePower(filterContext);
                }
            }
        }
        /// <summary>
        /// 检查是否登录
        /// </summary>
        /// <param name="filterContext"></param>
        /// <returns></returns>
        protected bool IsLogin(ActionExecutingContext filterContext)
        {
            UserProcess objUserProcess = new UserProcess();
            if (!objUserProcess.CheckOnLogin())
            {
                if (filterContext.HttpContext.Request.IsAjaxRequest())
                {
                    filterContext.Result = new ContentResult
                    {
                        Content = string.Format("对不起，因为你长时间未操作，所以请您重新登录")
                    };
                }
                else
                {
                    filterContext.Result = new ContentResult
                    {
                        Content = "<script type='text/javascript'>alert('对不起，因为你长时间未操作，所以请您重新登录');window.location.href='/home/userlogin';</script>"
                    };
                }
                return false;
            }
            if (!objUserProcess.CheckLogin())
            {
                if (filterContext.HttpContext.Request.IsAjaxRequest())
                {
                    filterContext.Result = new ContentResult
                    {
                        Content = string.Format("对不起，当前访问地址需要登录")
                    };
                }
                else
                {
                    filterContext.Result = new RedirectResult("/home/userlogin");
                }
                return false;
            }
            return true;
        }
        /// <summary>
        /// 检查访问权限
        /// </summary>
        /// <param name="filterContext"></param>
        protected void ChekePower(ActionExecutingContext filterContext)
        {
            string controllerName = filterContext.RouteData.GetRequiredString("controller");
            string actionName = filterContext.RouteData.GetRequiredString("action");
            string areaName = filterContext.RouteData.DataTokens["area"] != null ? filterContext.RouteData.DataTokens["area"].ToString() : "";
            BizPowerInfo objBizPowerInfo = new BizPowerInfo();
            var objPowerInfo = objBizPowerInfo.GetRecord(string.Format("ControllerName='{0}' AND ActionName='{1}' AND AreaName='{2}'", controllerName, actionName, areaName));
            if (objPowerInfo == null)
            {
                string errorMessage = string.Format("对不起,当前访问地址：【{0}】,未配置区域名称：【{1}】,控制器名称：【{2}】,Action名称：【{3}】,请与管理员联系", filterContext.HttpContext.Request.Url, areaName, controllerName, actionName);
                filterContext.Result = new ContentResult
                {
                    Content = errorMessage
                };
                LogHelper.WriteLog("权限配置错误", errorMessage, ModuleType.Power);
                return;
            }
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                return;
            }
            if (objPowerInfo.HasChild == 1)
            {
                var objButtonList = objBizPowerInfo.GetList(string.Format("ParentId={0} AND PowerType=2 AND IsDisplay=1", objPowerInfo.Id));
                if (objButtonList.IsNoNull())
                {
                    var objButtonTool = new ButtonTool();
                    PowerInfoComparer objPowerInfoComparer = new PowerInfoComparer();
                    objButtonList = objButtonList.Distinct(objPowerInfoComparer).OrderBy(c => c.SortIndex).ToList();
                    objButtonTool.AddItems(objButtonList.ConvertToButtonItemList().ToList());
                    filterContext.HttpContext.SetItems("ButtonTool", objButtonTool);
                }
            }
        }
        /// <summary>
        /// 检查用户访问权限
        /// </summary>
        /// <param name="filterContext"></param>
        protected void ChekeUserPower(ActionExecutingContext filterContext)
        {
            string controllerName = filterContext.RouteData.GetRequiredString("controller");
            string actionName = filterContext.RouteData.GetRequiredString("action");
            string areaName = filterContext.RouteData.DataTokens["area"] != null ? filterContext.RouteData.DataTokens["area"].ToString() : "";
            UserInfo objUserInfo = FormAuthHelper.GetUserTicket<UserInfo>();
            bool isAjaxRequest = filterContext.HttpContext.Request.IsAjaxRequest();
            if (objUserInfo == null)
            {
                if (filterContext.HttpContext.Request.IsAjaxRequest())
                {
                    filterContext.Result = new ContentResult
                    {
                        Content = string.Format("对不起，当前访问地址需要登录")
                    };
                }
                else
                {
                    filterContext.Result = new RedirectResult("/home/userlogin");
                }
                return;
            }
            UserProcess objUserProcess = new UserProcess();
            UserPowerType objUserPowerType;
            if (!Enum.TryParse<UserPowerType>(objUserInfo.PowerType.ToString(), out objUserPowerType))
            {
                filterContext.Result = new ContentResult
                {
                    Content = string.Format("对不起，访问权限类型异常")
                };
                return;
            }
            string dataObjectParam = objUserProcess.GetDataObjectParam(objUserPowerType);
            BizPowerInfo objBizPowerInfo = new BizPowerInfo(dataObjectParam);
            var objTable = objBizPowerInfo.GetViewDataTable(string.Format("UserId={0} AND ControllerName='{1}' AND ActionName='{2}' AND AreaName='{3}'", objUserInfo.Id, controllerName, actionName, areaName));
            if (objTable.IsNull())
            {
                string errorMessage = string.Format("对不起,您当前访问的地址没有权限：【{0}】,未配置区域名称：【{1}】,控制器名称：【{2}】,Action名称：【{3}】,请与管理员联系", filterContext.HttpContext.Request.Url, areaName, controllerName, actionName);
                filterContext.Result = new ContentResult
                {
                    Content = errorMessage
                };
                LogHelper.WriteLog("权限配置错误", errorMessage, ModuleType.Power);
                return;
            }
            if (isAjaxRequest)
            {
                return;
            }
            var objPowerInfo = objBizPowerInfo.ConvertToPowerInfo(objTable.Select().First());
            if (objPowerInfo.HasChild == 1)
            {
                objTable = objBizPowerInfo.GetViewDataTable(string.Format("UserId={0} AND ParentId={1} AND PowerType=2 AND IsDisplay=1", objUserInfo.Id, objPowerInfo.Id));
                if (objTable.IsNoNull())
                {
                    var objButtonList = objBizPowerInfo.ConvertToPowerInfoList(objTable);
                    var objButtonTool = new ButtonTool();
                    PowerInfoComparer objPowerInfoComparer = new PowerInfoComparer();
                    objButtonList = objButtonList.Distinct(objPowerInfoComparer).OrderBy(c => c.SortIndex).ToList();
                    objButtonTool.AddItems(objButtonList.ConvertToButtonItemList().ToList());
                    filterContext.HttpContext.SetItems("ButtonTool", objButtonTool);
                }

            }
        }
    }
}
